from flask import current_app, jsonify
from flask import json
from flask import request
import re
import random

from info import constants, db
from info import redis_store
from info.libs.yuntongxun.sms import CCP
from info.models import User
from info.utils.response_code import RET
from . import passport_blue
from info.utils.captcha.captcha import captcha


#　登录用户
#　请求路径 /passport/login
#　请求方式
#　请求参数
#　返回数据
@passport_blue.route('/login', methods=['POST'])
def login():
    """
    １．获取数据
    ２．校验数据
    ３．根据手机号码取出用户对象
    ４．判断密码的正确性
    ５．将用户的登录信息存到session
    ６．返回相应
    :return:
    """

    # １．获取数据
    dict_data = request.get_json()
    moblie = dict_data.get("moblie")
    password = dict_data.get("password")

    # ２．校验数据
    if not all([moblie, password]):
        return jsonify(reeon=RET.PARAMERR, errmsg="参数不完整")

    # ３．根据手机号码取出用户对象
    try:
         user = User.query.filter(User.mobile == moblie).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(reeon=RET.DBERR, errmsg="查询用户失败")

    # 判断用户是否存在
    if not user:
        return jsonify(reeon=RET.NODATA, errmsg="用户不存在")
    # ４．判断密码的正确性
    if not user:
        return jsonify(reeon=RET.DATAERR, errmsg="密码不正确")

    # ５．将用户的登录信息存到session

    # ６．返回相应
    return jsonify(reeon=RET.OK, errmsg="登录成功")


#注册用户
#请求路径"passport/register"
#请求方式
#请求参数
#返回值

@passport_blue.route('/register', methods=['POST'])
def register():
    """
    １．获取参数
    ２．校验参数是否为空
    ３．手机号码校验
    ４．根据手机号码取出redis中的短信验证码
    ５．校验短信验证码是否过期
    ６．校验短信验证码是否正确
    ７．创建对象对象
    ８．设置用户对象发的属性
    ９．保存用户到数据库
    １０．反馈相应信息
    :return:
    """

    # １．获取参数
    # json_data = request.data
    # dict_data = json.load(json_data)
    dict_data = request.json
    mobile = dict_data.get("mobile")
    sms_code = dict_data.get("sms_code")
    password = dict_data.get("password")

    # ２．校验参数是否为空
    if not all([mobile, sms_code, password]):
        return jsonify(reeor=RET.PARAMERR, reemsg="参数不完整")

    # ３．手机号码校验
    if not re.match('1[3456789]\\d{9}', mobile):
        return jsonify(reeon=RET.DATAERR, errmsg="手机号码有无")

    # ４．根据手机号码取出redis中的短信验证码
    try:
        redis_sms_code = redis_store.get("sms_code:%s"%mobile)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(reeon=RET.DBERR, errmsg="获取短信验证码失败")

    # ５．校验短信验证码是否过期
    if not redis_sms_code:
        return jsonify(reeon=RET.NODATA, errmsg="短信验证过期")

    # ６．校验短信验证码是否正确　
    if sms_code != redis_sms_code:
        return jsonify(reeon=RET.DATAERR, errmsg="短信验证码填写错误")

    # ７．创建用户对象
    user = User()

    # ８．色织用户对象发的属性
    user.nick_name = mobile
    user.password = password
    user.mobile = mobile
    # ９．保存用户到数据库
    try:
       db.session.add(user)
       db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(reeon=RET.DBERR, errmsg="用户创建失败")

    # １０．反馈相应信息
    return jsonify(reeon=RET.OK, errmsg="注册成功")



#　发送短信验证码
#　请求路径/passport/sms_code
# 请求方式post
#　请求参数　手机号　图片验证码　图片验证码编号
#　返回值　返回响应体

@passport_blue.route('/sms_code', methods=['POST'])
def send_message():
    """
    思路
    １．接受参数
    ２．验证参数
    ３．校验手机号码是否正确
    ４．通过验证码编号　取出图片验证码Ａ
    ５．判断验证码是否过期
    ６．判断验证码是否正确
    ７．调用ＣＣＰ发送短信
    ８．判断短信是否发送成功
    ９．保存短信到redis
    １０．饭随发送的状态
    :return:
    """

    # １．接受参数
    json_data = request.data
    dict_josn = json.loads(json_data)
    mobile = dict_josn.get("mobile")
    image_code = dict_josn.get("image_code")
    image_code_id = dict_josn.get("image_code_id")

    # ２．验证参数
    if not all([mobile, image_code, image_code_id]):
        return jsonify(reeor=RET.PARAMERR, reemsg="参数不完整")

    # ３．校验手机号码是否正确
    if not re.match('1[3456789]\\d{9}', mobile):
        return jsonify(reeon=RET.DATAERR, errmsg="手机号码有无")

    # ４．通过验证码编号　取出图片验证码Ａ
    try:
        redis_image_code = redis_store.get("image_code:%s"%image_code_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(reeon=RET.DBERR, errmsg="redis获取异常")

    # ５．判断验证码是否过期
    if not redis_image_code:
        return jsonify(reeon=RET.NODATA, errmsg="图片验证码过去")

    # ６．判断验证码是否正确
    if image_code.upper() != redis_image_code.upper():
        return jsonify(reeon=RET.DATAERR, errmsg="图片验证码不正确")

    # ７．调用ＣＣＰ发送短信
    sms_code = "%06d"%random .randint(0,999999)  #　发送六位随机短信验证码
    try:
        ccp = CCP()
        result = ccp.send_template_sms(mobile, [sms_code, constants.SMS_CODE_REDIS_EXPIRES/60], 1)
    except Exception as e:
        current_app.loggre.error(e)
        return jsonify(reeon=RET.THIRDERR, errmsg="云通讯发送异常")

    # ８．判断短信是否发送成功
    if result == -1:
        return jsonify(reeon=RET.DATAERR, errmsg="云通讯发送失败")

    # ９．保存短信到redis
    try:
        redis_store.set("sms_code:%s" % mobile, sms_code, constants.SMS_CODE_REDIS_EXPIRES)
    except Exception as e:
        current_app.loggre.error(e)
        return jsonify(reeon=RET.DBERR, errmsg="短信验证码保存异常")
    # １０．饭随发送的状态
    return jsonify(reeon=RET.OK, errmsg="短信发送成功")


# 生成图片验证码
# 请求路径：/passport/image_code  处理主蓝图　其他的访问搜要加前缀
# 请求方式　ＧＥＴ
# 携带的参数　浏览器随机生成字符串
# 返回图片验证


@passport_blue.route('/image_code')
def get_image_code():

    # 获取参数
    cur_id = request.args.get("cur_id")
    pre_id = request.args.get("pre_id")

    # 生成图片验证码
    name, text, image_data = captcha.generate_captcha()

    try:
        # 保存图片验证码-----模拟ｓｅｓｓｉｏｎ的储存方式－－－－－－－－设置时间
        redis_store.set("image_code:%s"%cur_id, text, constants.IMAGE_CODE_REDIS_EXPIRES)

        # 判断是否有第二张图片
        if pre_id:
            redis_store.delete("image_code:%s"%pre_id)
    except Exception as e:
        current_app.logger.error()
        return jsonify(erron=RET.DBERR, errmgs="redis操作异常")
    # 返回图片验证码
    return image_data